using System;
using System.Collections.Generic;
using System.IO;
using Common;
using Common.NotifyEvent;
using SProject.BasicInformation;
using SProject.Paramter;
using SProject.Program;
using SProject.Rule;

namespace SProject
{
	[Serializable]
	public class Project : NotifyPropertyChanged
	{
		public static string ProjectFileExt = "prj";

		public static string ProjectFileDotExt = "." + ProjectFileExt;

		[NonSerialized]
		private bool _IsEditing;

		[NonSerialized]
		private SLANClipboard _SLANClipboard = new SLANClipboard();

		private BasicInfo _BasicInfo = new BasicInfo();

		private Target _Target = new Target();

		private PCRProgram _PCRProgram;

		private BasicOption _BasicOption;

		private CrossTalk _CrossTalk = new CrossTalk();

		private SProject.Rule.Rule _Rule;

		public bool IsEditing
		{
			get
			{
				return _IsEditing;
			}
			set
			{
				_IsEditing = value;
			}
		}

		public SLANClipboard SLANClipboard
		{
			get
			{
				return _SLANClipboard;
			}
		}

		public BasicInfo BasicInfo
		{
			get
			{
				return _BasicInfo;
			}
			set
			{
				if (_BasicInfo != value)
				{
					BasicInfo basicInfo = _BasicInfo;
					_BasicInfo = value;
					OnPropertyChanged("BasicInfo", _BasicInfo, basicInfo);
				}
			}
		}

		public Target Target
		{
			get
			{
				return _Target;
			}
			set
			{
				if (_Target != value)
				{
					_Target = value;
					OnPropertyChanged("Target");
				}
			}
		}

		public PCRProgram PCRProgram
		{
			get
			{
				return _PCRProgram;
			}
			set
			{
				if (_PCRProgram != value)
				{
					_PCRProgram = value;
					OnPropertyChanged("PCRProgram");
				}
			}
		}

		public BasicOption BasicOption
		{
			get
			{
				return _BasicOption;
			}
			set
			{
				if (_BasicOption != value)
				{
					_BasicOption = value;
					OnPropertyChanged("BasicOption");
				}
			}
		}

		public CrossTalk CrossTalk
		{
			get
			{
				return _CrossTalk;
			}
			set
			{
				if (_CrossTalk != value)
				{
					_CrossTalk = value;
					OnPropertyChanged("CrossTalk");
				}
			}
		}

		public SProject.Rule.Rule Rule
		{
			get
			{
				return _Rule;
			}
			set
			{
				if (_Rule != value)
				{
					_Rule = value;
					OnPropertyChanged("Rule");
				}
			}
		}

		public string Password { get; set; }

		public Project()
		{
			RegisterEvent();
			RefreshBasicOption();
			CreateNewPCRProgram();
		}

		public Project(Project project)
			: this()
		{
			Copy(project);
			RegisterEvent();
		}

		private void RegisterEvent()
		{
			_BasicInfo.Event += _BasicInfo_Event;
		}

		private void _BasicInfo_Event(object sender, EventArgs e)
		{
			PropertyChangedEventArgsEx propertyChangedEventArgsEx = e as PropertyChangedEventArgsEx;
			if (propertyChangedEventArgsEx != null && propertyChangedEventArgsEx.PropertyName == "Type")
			{
				RefreshBasicOption();
				CreateNewPCRProgram();
				Target = new Target();
				CrossTalk = new CrossTalk();
			}
		}

		private void CreateNewPCRProgram()
		{
			PCRProgram pCRProgram = new PCRProgram();
			PCRProgram pCRProgram2 = new PCRProgram();
			if (PCRProgramManage.GetInstance().AllProgramList.ContainsKey(BasicInfo.Type))
			{
				pCRProgram = PCRProgramManage.GetInstance().AllProgramList[BasicInfo.Type];
			}
			pCRProgram2.Copy(pCRProgram);
			PCRProgram = pCRProgram2;
		}

		private void RefreshBasicOption()
		{
			BasicOption = OptionFactory.CreateBasicOption(BasicInfo.Type);
			Rule = RuleFactory.CreateRule(BasicInfo.Type);
		}

		public void Copy(Project project)
		{
			string systemTempFile = Utility.GetSystemTempFile();
			project.SaveAs(systemTempFile, true);
			Project project2 = Load(systemTempFile);
			project2.BasicInfo.Name = project.BasicInfo.Name;
			BasicInfo = project2.BasicInfo;
			Target = project2.Target;
			PCRProgram = project2.PCRProgram;
			BasicOption = project2.BasicOption;
			CrossTalk = project2.CrossTalk;
			Rule = project2.Rule;
			Password = project2.Password;
		}

		public void Save()
		{
			SaveAs(Utility.GetProjectPath());
		}

		public string GetFilePath()
		{
			return Utility.GetProjectPath() + BasicInfo.Name + ProjectFileDotExt;
		}

		public bool SaveAs(string path, bool includeName = false)
		{
			bool result = false;
			if (path == null || path.Length == 0)
			{
				return result;
			}
			if (!includeName && path.LastIndexOf("\\") != path.Length - 1)
			{
				path += "\\";
			}
			string path2 = (includeName ? path : (path + BasicInfo.Name + ProjectFileDotExt));
			FileStream fileStream = null;
			StreamEx streamEx = new StreamEx();
			try
			{
				fileStream = new FileStream(path2, FileMode.Create, FileAccess.Write);
				SaveToStream(streamEx);
				streamEx.Seek(0L, SeekOrigin.Begin);
				streamEx.CopyTo(fileStream);
				result = true;
			}
			catch (Exception ex)
			{
				Log.WriteLine(string.Format("Save Project Error:{0}", ex.Message));
			}
			finally
			{
				if (streamEx != null)
				{
					streamEx.Close();
				}
				if (fileStream != null)
				{
					fileStream.Close();
				}
			}
			return result;
		}

		public void SaveToStream(StreamEx stream)
		{
			List<PropertyKey> list = new List<PropertyKey>();
			List<byte[]> list2 = new List<byte[]>();
			list.Add(PropertyKey.Key_Version);
			list2.Add(BytesConverter.GetBytes(Utility.GetProductFileVersion()));
			if (!string.IsNullOrEmpty(Password))
			{
				list.Add(PropertyKey.Key_Password);
				list2.Add(BytesConverter.GetBytes(Password));
			}
			StreamEx streamEx = new StreamEx();
			BasicInfo.SaveToStream(streamEx);
			list.Add(PropertyKey.Key_ProjectBasicInfo);
			list2.Add(streamEx.ToArray());
			streamEx.Close();
			streamEx = new StreamEx();
			Target.SaveToStream(streamEx);
			list.Add(PropertyKey.Key_ProjectTarget);
			list2.Add(streamEx.ToArray());
			streamEx.Close();
			streamEx = new StreamEx();
			PCRProgram.SaveToStream(streamEx);
			list.Add(PropertyKey.Key_ProjectPcr);
			list2.Add(streamEx.ToArray());
			streamEx.Close();
			streamEx = new StreamEx();
			BasicOption.SaveToStream(streamEx);
			list.Add(PropertyKey.Key_ProjectBasicOption);
			list2.Add(streamEx.ToArray());
			streamEx.Close();
			streamEx = new StreamEx();
			CrossTalk.SaveToStream(streamEx);
			list.Add(PropertyKey.Key_ProjectCrossTalk);
			list2.Add(streamEx.ToArray());
			streamEx.Close();
			streamEx = new StreamEx();
			Rule.SaveToStream(streamEx);
			list.Add(PropertyKey.Key_ProjectRule);
			list2.Add(streamEx.ToArray());
			streamEx.Close();
			stream.Write(PropertyKey.Key_Index);
			stream.WriteIndex(list, list2);
			stream.Flush();
		}

		public bool ReadFromStream(StreamEx stream)
		{
			PropertyKey propertyKey = stream.ReadKey();
			switch (propertyKey)
			{
			case PropertyKey.Key_Index:
			{
				List<PropertyKey> keys;
				List<byte[]> dates;
				stream.ReadIndex(out keys, out dates);
				bool flag = true;
				for (int i = 0; i < keys.Count; i++)
				{
					if (!flag)
					{
						return false;
					}
					switch (keys[i])
					{
					case PropertyKey.Key_Version:
						BytesConverter.BytesToString(dates[i]);
						break;
					case PropertyKey.Key_Password:
						Password = BytesConverter.BytesToString(dates[i]);
						break;
					case PropertyKey.Key_ProjectBasicInfo:
					{
						StreamEx streamEx = new StreamEx();
						streamEx.Write(dates[i]);
						streamEx.Seek(0L, SeekOrigin.Begin);
						flag = BasicInfo.ReadFromStream(streamEx);
						streamEx.Close();
						break;
					}
					case PropertyKey.Key_ProjectTarget:
					{
						StreamEx streamEx = new StreamEx();
						streamEx.Write(dates[i]);
						streamEx.Seek(0L, SeekOrigin.Begin);
						flag = Target.ReadFromStream(streamEx);
						streamEx.Close();
						break;
					}
					case PropertyKey.Key_ProjectPcr:
					{
						StreamEx streamEx = new StreamEx();
						streamEx.Write(dates[i]);
						streamEx.Seek(0L, SeekOrigin.Begin);
						flag = PCRProgram.ReadFromStream(streamEx);
						streamEx.Close();
						break;
					}
					case PropertyKey.Key_ProjectBasicOption:
					{
						StreamEx streamEx = new StreamEx();
						streamEx.Write(dates[i]);
						streamEx.Seek(0L, SeekOrigin.Begin);
						flag = BasicOption.ReadFromStream(streamEx);
						streamEx.Close();
						break;
					}
					case PropertyKey.Key_ProjectCrossTalk:
					{
						StreamEx streamEx = new StreamEx();
						streamEx.Write(dates[i]);
						streamEx.Seek(0L, SeekOrigin.Begin);
						flag = CrossTalk.ReadFromStream(streamEx);
						streamEx.Close();
						break;
					}
					case PropertyKey.Key_ProjectRule:
					{
						StreamEx streamEx = new StreamEx();
						streamEx.Write(dates[i]);
						streamEx.Seek(0L, SeekOrigin.Begin);
						flag = Rule.ReadFromStream(streamEx);
						streamEx.Close();
						break;
					}
					}
				}
				return true;
			}
			case PropertyKey.Key_Version:
				stream.ReadString();
				propertyKey = stream.ReadKey();
				break;
			}
			if (propertyKey == PropertyKey.Key_Password)
			{
				Password = stream.ReadString();
			}
			else
			{
				stream.Seek(-4L, SeekOrigin.Current);
			}
			if (BasicInfo.ReadFromStream(stream) && Target.ReadFromStream(stream) && PCRProgram.ReadFromStream(stream) && BasicOption.ReadFromStream(stream) && CrossTalk.ReadFromStream(stream))
			{
				return Rule.ReadFromStream(stream);
			}
			return false;
		}

		public void Rename(string name)
		{
			DeleteFile();
			BasicInfo.Name = name;
			Save();
		}

		public void DeleteFile()
		{
			string path = Utility.GetProjectPath() + BasicInfo.Name + ProjectFileDotExt;
			if (File.Exists(path))
			{
				File.Delete(path);
			}
		}

		public static Project Load(string path)
		{
			if (path == null || path.Length == 0)
			{
				return null;
			}
			Project project = null;
			Project project2 = new Project();
			FileStream fileStream = null;
			StreamEx streamEx = new StreamEx();
			try
			{
				fileStream = new FileStream(path, FileMode.Open, FileAccess.Read);
				fileStream.CopyTo(streamEx);
				streamEx.Seek(0L, SeekOrigin.Begin);
				if (project2.ReadFromStream(streamEx))
				{
					project = project2;
				}
			}
			catch (Exception ex)
			{
				Log.WriteLine(string.Format("Load Project Error:{0}", ex.Message));
			}
			finally
			{
				if (streamEx != null)
				{
					streamEx.Close();
				}
				if (fileStream != null)
				{
					fileStream.Close();
				}
			}
			if (project != null)
			{
				project.BasicInfo.Name = Path.GetFileNameWithoutExtension(path);
			}
			return project;
		}

		public void UpdataTarget(Target target)
		{
			Target = target;
			for (int num = BasicOption.Items.Count - 1; num >= 0; num--)
			{
				BasicOptionItem basicOptionItem = BasicOption.Items[num];
				bool flag = false;
				bool flag2 = false;
				foreach (TargetItem item in Target.Items)
				{
					if (item.ChannelNo == basicOptionItem.ChannelNo)
					{
						flag = true;
						if (item.TubeNo == basicOptionItem.TubeNo)
						{
							basicOptionItem.TubeName = item.TubeName;
							flag2 = true;
							break;
						}
					}
				}
				if (!flag2)
				{
					BasicOption.Items.RemoveAt(num);
				}
				if (!flag)
				{
					CrossTalk.DeleteCrossTalkChannel(basicOptionItem.ChannelNo);
				}
			}
			foreach (TargetItem item2 in Target.Items)
			{
				BasicOption.AddBasicOptionItem(item2.TubeNo, item2.ChannelNo, item2.Name, item2.TubeName);
				CrossTalk.AddCrossTalkChannel(item2.ChannelNo);
			}
		}
	}
}
